'use strict'

// const util = require('util')
const fs = require('fs')
const path = require('path')
const events = require('events')
const _uuid = require('uuid/v4')
let staticPath = ''


export function uuid () {
  return _uuid()
}

/**
 * 获取随机id
 * @param num id的长度
 * @returns {string}
 */
export function getRandomId (num = 10) {
  const arr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let id = ''
  for (let i = 0; i < num; i++) {
    let index = Math.floor(Math.random() * arr.length)
    id += arr[index]
  }
  return id
}

/**
 * 获取某个html元素的定位
 */
export function getPos (el, pEl) {
  let pos = {}
  pos.x = el.offsetLeft
  pos.y = el.offsetTop
  while ((el = el.offsetParent)) {
    if (el === pEl) break
    pos.x += el.offsetLeft
    pos.y += el.offsetTop
  }
  pos.height = pEl ? pEl.offsetHeight : window.innerHeight
  pos.width = pEl ? pEl.offsetWidth : window.innerWidth
  return pos
}

export function getPosFromScreen (el) {
  let pos = {}
  pos.x = el.offsetLeft
  pos.y = el.offsetTop
  while ((el = el.offsetParent)) {
    pos.x += el.offsetLeft
    pos.y += el.offsetTop
  }
  pos.x += window.screenX
  pos.y += window.screenY
  return pos
}

export function getCatalogML (arr) {
  for (let i = 0; i < arr.length; i++) {
    let node = arr[i]
    if (Number(node.type) !== 0) {
      arr.splice(i, 1)
      i--
    } else if (node.children) {
      getCatalogML(node.children)
    }
  }
  return arr
}

/**
 * 判断目标是否不为空
 * @param target 对传入的参数判断是否非空
 * @returns {boolean}
 */
export function isNotEmpty (target) {
  if (Array.isArray(target)) {
    return target.length !== 0
  } else if (typeof target === 'object') {
    for (let name in target) {
      return true
    }
    return false
  } else {
    return !!target
  }
}

export function isObeject (obj) {
  return Object.prototype.toString.call(obj) === '[object Object]'
}

export function isArray (obj) {
  return Object.prototype.toString.call(obj) === '[object Array]'
}

/**
 * 复制文件
 * @param src 源文件
 * @param dest 目标文件
 */
export function copyFile (src, dest) {
  if (fs.existsSync(path.dirname(dest))) {
  } else {
    fs.mkdirSync(path.dirname(dest))
  }
  const ev = new events.EventEmitter()
  const totalSize = fs.statSync(src).size
  let loaded = 0
  let ws = fs.createWriteStream(dest)
  let rs = fs.createReadStream(src)
  ws.on('finish', () => {
    ev.emit('end')
  })
  rs.on('data', (chunk) => {
    loaded += chunk.length
    ev.emit('process', Math.ceil(loaded / totalSize * 100))
  })
  rs.pipe(ws)
  return ev
}

/**
 * 复制文件
 * @param src 源文件
 * @param dest 目标文件
 */
export function copyFileSync (src, dest) {
  if (fs.existsSync(path.dirname(dest))) {
  } else {
    fs.mkdirSync(path.dirname(dest))
  }
  return new Promise((resolve, reject) => {
    let ws = fs.createWriteStream(dest)
    let rs = fs.createReadStream(src)
    ws.on('finish', () => {
      resolve()
    })
    rs.pipe(ws)
  })
}

/**
 *  将base64转为Uint8Array
 * @param dataURI base64字符串
 * @returns {*}
 */
export function convertDataURI (dataURI) {
  const base64Str = /data:(\w+)\/(\w+)+;base64,/i
  if (!base64Str.test(dataURI)) throw new Error('请检查base64格式是否正确')
  let BASE64_MARKER = ';base64,'
  let base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length
  let base64 = dataURI.substring(base64Index)
  let raw = window.atob(base64)
  let rawLength = raw.length
  let array = new Uint8Array(new ArrayBuffer(rawLength))

  for (let i = 0; i < rawLength; i++) {
    array[i] = raw.charCodeAt(i)
  }
  return array
}

/**
 * 获取树数据
 * @param dataSource 数据源数组
 * @param majorKey id
 * @param parentKey pid
 * @param majorValue 最外层pid的值
 * @returns {Array} el-tree数据
 */
// export function getTreeDataSource(dataSource, majorKey, parentKey, majorValue) {
//   let treeDataSource = [];
//   let filterSource = dataSource.filter(x => {
//     return x[parentKey] == majorValue;
//   });
//   for (let i = 0; i < filterSource.length; i++) {
//     let childrenNode = getTreeDataSource(dataSource, majorKey, parentKey, filterSource[i][majorKey]);
//     let node = {...filterSource[i]}
//     if (childrenNode.length) node.children = childrenNode
//     treeDataSource.push(node);
//   }
//   return treeDataSource;
// }

/**
 * 获取树数据
 * @param dataSource 数据源数组
 * @param majorKey id
 * @param parentKey pid
 * @param majorValue 最外层pid的值
 * @param isParentKeyValue majorValue的值是否为pid的值
 * @returns {Array} el-tree数据
 */
export function getEvidenceMaterialTree (dataSource = [], majorValue = '', index = 0, isRootNode = true, majorKey = 'NodeID', parentKey = 'NodeParentID') {
  let treeDataSource = []
  let filterSource = dataSource.filter((x) => {
    return x[parentKey] === majorValue
  }).sort((a, b) => {
    return a.order - b.order
  })
  for (let i = 0; i < filterSource.length; i++) {
    filterSource[i].order = index++
    // if (filterSource[i].FileType === 'file') {
    //   treeDataSource.push(filterSource[i])
    // } else {
    let arr = getEvidenceMaterialTree(dataSource, filterSource[i][majorKey], index, false, majorKey, parentKey)
    let catalog = {...filterSource[i]}
    if (arr.treeDataSource.length) catalog.children = arr.treeDataSource
    treeDataSource.push(catalog)

    index = arr.index
    // }
  }
  return isRootNode ? treeDataSource : {treeDataSource, index}
}

/**
 * 获取树数据
 * @param dataSource 数据源数组
 * @param majorKey id
 * @param parentKey pid
 * @param majorValue 最外层pid的值
 * @param isParentKeyValue majorValue的值是否为pid的值
 * @returns {Array} el-tree数据
 */
export function getTreeDataSource (dataSource = [], majorKey, parentKey, majorValue, isParentKeyValue = true) {
  let treeDataSource = []

  let filterSource = []

  // 获取所有的根节点；
  if (majorValue) {
    if (isParentKeyValue) {
      filterSource = dataSource.filter((item) => item[parentKey] === majorValue)
    } else {
      let _item = dataSource.find((item) => item[majorKey] === majorValue)
      if (!_item) return treeDataSource
      filterSource = dataSource.filter((item) => item[parentKey] === _item[parentKey] && item[majorKey] === majorValue)
    }
  } else {
    filterSource = dataSource.filter((item) => !dataSource.some((_item) => _item[majorKey] === item[parentKey]))
  }

  // 从数据源中去除所有根节点
  for (let item of filterSource) {
    let index = dataSource.findIndex((_item) => _item[majorKey] === item[majorKey])
    if (index > -1) dataSource.splice(index, 1)
  }

  // 通过父节点的主键值获取其所有子节点
  function getChildrenByParentMajorValue (_majorValue) {
    let _treeDataSource = []
    let _filterSource = dataSource.filter((x) => x[parentKey] === _majorValue)

    // 从数据源中去除所有符合条件的节点
    for (let item of _filterSource) {
      let index = dataSource.findIndex((_item) => _item[majorKey] === item[majorKey])
      if (index > -1) dataSource.splice(index, 1)
    }

    for (let item of _filterSource) {
      let childrenNode = getChildrenByParentMajorValue(item[majorKey])
      let node = {...item}
      delete node.filter
      if (childrenNode.length) node.children = childrenNode
      _treeDataSource.push(node)
    }
    return _treeDataSource
  }

  for (let item of filterSource) {
    item.children = getChildrenByParentMajorValue(item[majorKey])

    treeDataSource.push(item)
  }
  return treeDataSource
}

let queueArr = []
let running = false

/**
 * 队列
 * @param options
 * @param callback
 */
export async function queue ({data, id}, callback) {
  if (!(id in data)) throw new Error(`${id} 不是data的属性`)
  if (running) {
    let isExist = queueArr.findIndex((item) => item[id] === data[id]) > -1
    isExist || queueArr.push(data)
    return
  }
  running = true
  callback(data).then(() => {
    let index = queueArr.findIndex((item) => item[id] === data[id])
    if (index > -1) queueArr.splice(index, 1)
    running = false
    if (queueArr.length) queue({data: queueArr[0], id}, callback)
  })
}

export function getTreeNodes (tree = [], nodes) {
  nodes = nodes || []
  for (let node of tree) {
    nodes.push(node)
    if (node.children) getTreeNodes(node.children, nodes)
  }
  return nodes
}

/**
 * 插入到指定元素之后
 * @param targetElement
 * @param newElement
 */
export function insertAfter (targetElement, newElement) {
  var parent = targetElement.parentNode
  if (parent.lastChild === targetElement) {
    parent.appendChild(newElement)
  } else {
    parent.insertBefore(newElement, targetElement.nextSibling)
  }
}

/**
 * 文本转为图片
 * @param text 要显示的文本
 * @param options
 * @returns {string}
 */
export function textToImg (text, options = {}) {
  let len = 0
  for (let i = 0; i < text.length; i++) {
    len += text.charAt(i).match(/[^\x00-\xff]/ig) != null ? 1 : 0.5
  }
  // 1 pt = px * 96/72 = px * 4/3
  options.fontSize = options.fontSize || '15px'
  if (!options.hasOwnProperty('underline')) options.underline = true
  let res = options.fontSize.match(/(\d+)([a-zA-Z]+)/)

  let fontSize = res[1]

  if (res[2] === 'pt') fontSize = 4 / 3 * fontSize

  let canvas = document.createElement('canvas')
  canvas.width = fontSize * len
  canvas.height = fontSize * 1.4
  let context = canvas.getContext('2d')

  if (options.background) {
    context.fillStyle = options.background || 'transparent'
    context.fillRect(0, 0, canvas.width, canvas.height)
  }

  context.fillStyle = options.color || 'black'
  context.strokeStyle = options.color || 'black'

  let fontWeight = options.fontWeight || 'normal'
  let font = options.font || '微软雅黑'
  context.font = `${fontWeight} ${fontSize}px ${font}`
  context.textBaseline = 'bottom'
  if (options.underline) {
    context.fillText(text, 0, canvas.height - 1, canvas.width)
  } else {
    context.fillText(text, 0, canvas.height + 3, canvas.width)
  }
  if (options.underline) {
    context.lineWidth = 1
    context.moveTo(0, canvas.height - 1)
    context.lineTo(canvas.width - 2, canvas.height - 1)
    context.stroke()
  }

  return canvas.toDataURL('image/png')
}

export function getBase64 (url, type = 'png') {
  if (!staticPath) return `${process.env.BASE_URL}static${url}`
  return `data:image/${type};base64,${fs.readFileSync(staticPath + url).toString('base64')}`
}

/*****************************************************************************/

export function getEvidenceCatalogTreeNode (item) {
  let ext = item.WJHZ || item.WJKZM
  return {
    id: item.NodeID,
    pid: item.NodeParentID,
    name: item.MLXSMC,
    type: item.FileType !== 'dir' ? 1 : 0,
    alias: item.MLXSMC,
    suffix: ext,
    show: true,
    fileType: /mp4/i.test(ext) ? 'MEDIA' : (/mp3/i.test(ext) ? 'AUDIO' : 'IMAGE'),
    fileID: item.ID,
    style: item.style,
    template: item.template
  }
}

/**
 *
 * @param nodes
 */
export function getPrePushNodes (nodes) {
  let _nodes = []
  nodes.forEach((item) => _nodes.push(getEvidenceCatalogTreeNode(item)))

  let prePushNodes = []
  // 获取所有的父级node
  let pids = []
  let pNodes = _nodes.filter((item) => !_nodes.some((_item) => _item.id === item.pid))

  pNodes.forEach((item) => {
    let isExist = pids.some((_item) => _item === item.pid)
    if (isExist) return
    pids.push(item.pid)
  })
  pids.forEach((pid) => {
    prePushNodes = [...prePushNodes, ...getTreeDataSource(_nodes, 'id', 'pid', pid)]
  })
  return recursionUpdateIdAndPid(prePushNodes)
}

/**
 * 递归修改id和pid
 * @param data
 * @param pid
 * @returns {Array}
 */
export function recursionUpdateIdAndPid (data = [], pid = _guid.raw()) {
  for (let i = 0; i < data.length; i++) {
    let _data = data[i]
    _data.pid = pid
    _data.id = _guid.raw()
    if (_data.children) {
      recursionUpdateIdAndPid(_data.children, _data.id)
    }
  }
  return data
}

export function getNewMonth (date, isNext = false) {
  let arr = date.split('-')
  let year = arr[0] // 获取当前日期的年份
  let month = arr[1] // 获取当前日期的月份
  let year2 = year
  let month2 = isNext ? parseInt(month) + 1 : parseInt(month) - 1
  if (month2 === 0) {
    year2 = parseInt(year2) - 1
    month2 = 12
  } else if (month2 === 13) {
    year2 = parseInt(year2) + 1
    month2 = 1
  }
  if (month2 < 10) month2 = '0' + month2

  let t2 = year2 + '-' + month2
  return new Date(t2)
}

export function getMonthData (_date) {
  let date = new Date(_date)
  let today = new Date()
  // let weekStr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  // let weekStrZh = ['日', '一', '二', '三', '四', '五', '六'];
  let data = []

  // 当前月第一天
  let _firstDay = new Date(date.getFullYear(), date.getMonth(), 1)

  for (let i = 0; i < 42; i++) { // 6个周
    let _thisDay = new Date(date.getFullYear(), date.getMonth(), i + 1 - _firstDay.getDay())
    data[i] = {
      day: _thisDay.getDate(),
      month: _thisDay.getMonth() + 1,
      year: _thisDay.getFullYear(),
      // weekName: weekStrZh[index],
      // weekIndex: index,
      isToday: today.getFullYear() === _thisDay.getFullYear() && today.getMonth() === _thisDay.getMonth() && today.getDate() === _thisDay.getDate(),
      isToMonth: today.getFullYear() === _thisDay.getFullYear() && _thisDay.getMonth() === today.getMonth(),
      isToYear: today.getFullYear() === _thisDay.getFullYear(),
      isCurrentMonth: date.getFullYear() === _thisDay.getFullYear() && _thisDay.getMonth() === date.getMonth()
    }
  }
  return data
}

export function _getMonthData (_date) {
  let date = new Date(_date)
  // let today = new Date()
  // let weekStr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  // let weekStrZh = ['日', '一', '二', '三', '四', '五', '六'];
  let data = []

  // 当前月第一天
  let _firstDay = new Date(date.getFullYear(), date.getMonth(), 1)

  for (let i = 0; i < 42; i++) { // 6个周
    let _thisDay = new Date(date.getFullYear(), date.getMonth(), i + 1 - _firstDay.getDay())
    data[i] = [_thisDay.Format('yyyy-MM-dd')]
    // {
    // date: _thisDay.Format('yyyy-MM-dd'),
    // day: _thisDay.getDate(),
    // month: _thisDay.getMonth() + 1,
    // year: _thisDay.getFullYear(),
    // weekName: weekStrZh[index],
    // weekIndex: index,

    // 今日
    // isCurrentday: today.getFullYear() === _thisDay.getFullYear() && today.getMonth() === _thisDay.getMonth() && today.getDate() === _thisDay.getDate(),

    // 是否日历显示年
    // isToYear: today.getFullYear() === _thisDay.getFullYear(),

    // 是否日历显示月
    // isToMonth: date.getFullYear() === _thisDay.getFullYear() && _thisDay.getMonth() === date.getMonth(),

    // 本月
    // isCurrentMonth: today.getFullYear() === _thisDay.getFullYear() && _thisDay.getMonth() === today.getMonth(),
    // };
  }
  return data
}

export function insertText (str, win) {
  win = win || window || null
  if (!win) throw new Error('获取不到window')
  if (!win.getSelection) throw new Error('该浏览器不支持')

  // 获取selection
  let selection = win.getSelection()
  // 获取选中内容的开始位置
  let range = selection.getRangeAt(0)
  // 删除选中的内容
  range.deleteContents()
  // 将传入的text转换为Node类型
  let span = document.createElement('span')
  span.innerText = str
  let frag = document.createDocumentFragment()
  let lastNode = frag.appendChild(span)
  range.insertNode(frag)
  if (!lastNode) return ''
  range = range.cloneRange()
  range.setStartAfter(lastNode)
  range.collapse(true)
  selection.removeAllRanges()
  selection.addRange(range)
}

export function insertHtml (html, el, win) {
  // 使编辑框获取焦点
  win = win || window || null
  if (!win) throw new Error('获取不到window')
  if (!win.getSelection) throw new Error('该浏览器不支持')

  el.focus()
  if (!win.getSelection) return ''
  // 获取selection
  let sel = win.getSelection()
  if (!(sel.getRangeAt && sel.rangeCount)) return ''
  // 获取选中内容的开始位置
  let range = sel.getRangeAt(0)
  // 删除选中的内容
  range.deleteContents()
  // 将传入的html转换为Node类型
  let div = document.createElement('div')
  div.innerHTML = html
  let node = div.firstChild
  let frag = document.createDocumentFragment()
  let lastNode = frag.appendChild(node)
  range.insertNode(frag)
  if (!lastNode) return ''
  range = range.cloneRange()
  range.setStartAfter(lastNode)
  range.collapse(true)
  sel.removeAllRanges()
  sel.addRange(range)
}

export function getSize (size) {
  let units = ['B', 'KB', 'MB', 'GB', 'TB']
  let unitIndex = 0
  while (size > 1024) {
    size = Math.round(parseFloat(size / 1024) * 10) / 10
    unitIndex++
  }
  return size + units[unitIndex]
}

// 对字符串进行加密
export function compileStr (code) {
  if (typeof code === 'number') code += ''
  if (!code) return code
  var c = String.fromCharCode(code.charCodeAt(0) + code.length)
  for (var i = 1; i < code.length; i++) {
    c += String.fromCharCode(code.charCodeAt(i) + code.charCodeAt(i - 1))
  }
  return escape(c)
}

// 字符串进行解密
export function uncompileStr (code) {
  if (typeof code === 'number') code += ''
  if (!code) return code
  code = unescape(code)
  var c = String.fromCharCode(code.charCodeAt(0) - code.length)
  for (var i = 1; i < code.length; i++) {
    c += String.fromCharCode(code.charCodeAt(i) - c.charCodeAt(i - 1))
  }
  return c
}
